# -*- coding: utf-8 -*-
# @Time : 2019/8/24 17:58
# @Author : ricky
# @File : main.py
# @Software: vscode
"""主界面"""
import sys
import os
import subprocess
import threading
import zipfile
import datetime
import wx
import wx.adv
import ui.main.main_frame as frame
import ui
from loguru import logger
from constant import constant
from spider import upgradespider
from utils import configini
from utils import path
from core import alterparam
from core import ruoyi
from core import ruoyicloud
from core import ruoyifast
from core import ruoyivue


class Main(frame.MainFrame):
    def __init__(self, parent):
        frame.MainFrame.__init__(self, parent)
        self.icon = wx.Icon(
            path.resource_path(constant.APP_BITMAP_TYPE_ICO),
            wx.BITMAP_TYPE_ICO)
        self.SetIcon(self.icon)

        # 记录当前工作目录
        globals()[constant.APP_WORK_DIRECTORY] = os.getcwd()
        self.m_filePicker.GetPickerCtrl().SetLabel('选择文件')
        self.m_filePicker.GetTextCtrl().SetHint('请选择从官网下载下来的“.zip”后缀的压缩文件')

        self.m_text_ctrl_project_dir_name.SetHint('请输入目录名称')
        self.m_text_ctrl_project_name.SetHint('请输入项目名称')
        self.m_text_ctrl_package_name.SetHint('请输入包名')
        self.m_text_ctrl_artifact_id.SetHint('请输入artifactId')
        self.m_text_ctrl_group_id.SetHint('请输入groupId')
        self.m_text_ctrl_site_name.SetHint('请输入站点名称')

        self.m_statusbar.SetFieldsCount(4)  # 状态栏分成4个区域
        #self.m_statusbar.SetStatusWidths([-5,-2]) #区域宽度比列，用负数
        self.m_statusbar.SetStatusText('  软件版本：' + constant.APP_VERSION_STRING,
                                       0)
        self.m_statusbar.SetStatusText(
            '  Python版本：' + constant.PYTHON_VERSION_STRING, 1)
        self.m_statusbar.SetStatusText(
            '  WxPython版本：' + constant.WXPYTHON_VERSION_STRING, 2)
        self.m_statusbar.SetStatusText('  联系作者(RICKY)：QQ11748854', 3)
        self.Centre()

    def show_message(self, message):
        """
        统一显示对话框

        参数:
                message (str): 对话框内容
        """
        wx.MessageDialog(self, message, '操作提醒', wx.OK).ShowModal()

    def show_operate_log(self, log):
        """
        统一显示日志到控件

        参数:
            self (object): 当前对象
            log (str): 日志内容
        """
        # 这里要在主线程更新UI，否则会报错
        wx.CallAfter(self.m_text_log.AppendText, log + '\n')
        self.m_text_log.ShowPosition(self.m_text_log.GetLastPosition())

    def alter_callback(self, message):
        """
        修改回调处理

        参数:
            self (object): 上下文对象
            message (str): 消息
        """
        self.show_operate_log(message)

    def check_input(self):
        """
        校验输入框

        参数:
            self (object): 当前对象
        Return:
            提示消息,校验通过返回''
        """
        message = ''
        # 验证输入框是否有值
        if len(self.m_text_ctrl_project_dir_name.GetValue()) == 0:
            message = '请填写目录名称'
        if len(self.m_text_ctrl_project_name.GetValue()) == 0:
            message = '请填写项目名'
        if len(self.m_text_ctrl_package_name.GetValue()) == 0:
            message = '请填写包名'
        if len(self.m_text_ctrl_artifact_id.GetValue()) == 0:
            message = '请填写artifactId'
        if len(self.m_text_ctrl_group_id.GetValue()) == 0:
            message = '请填写groupId'
        if len(self.m_text_ctrl_site_name.GetValue()) == 0:
            message = '请填写站点名称'
        return message

    def start_task(self, select_path):
        """
        开始任务

        参数:
            self (object): 当前对象
            select_path (str): 选择的文件路径
        """
        self.m_text_log.Clear()
        self.show_operate_log('任务开始!')
        #禁用按钮
        self.m_btn_start.Disable()
        self.m_btn_clear.Disable()
        self.m_btn_open_output_directory.Disable()
        self.show_operate_log('正在检测文件...')
        file_path, file_name = os.path.split(select_path)
        # 切换当前工作目录
        os.chdir(file_path)
        # 目标目录
        target_dir = os.getcwd() + os.path.sep + datetime.datetime.now(
        ).strftime('%Y%m%d%H%M%S')
        # 如果目标目录不存在，创建目录
        if not os.path.exists(target_dir):
            os.makedirs(target_dir)
        # 解压到指定的文件夹
        with zipfile.ZipFile(file_name, 'r') as zip_file:
            zip_file.extractall(target_dir)

        self.show_operate_log('输出目录：' + target_dir)
        self.show_operate_log('解压完成，正在修改文件请稍后...')
        # 读取配置文件
        configdict = configini.Config().get_dict()
        # 读取模板配置文件
        tpath = os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), 'template_config.ini')
        if not os.path.exists(tpath):
            tpath = path.resource_path('conf/template_config.ini')
        templatedict = configini.Config(tpath).get_dict()
        # 构造参数
        params = alterparam.AlterParam()
        params.context = self
        params.targetdir = target_dir
        params.sitename = self.m_text_ctrl_site_name.GetValue()
        params.projectdirname = self.m_text_ctrl_project_dir_name.GetValue()
        params.packagename = self.m_text_ctrl_package_name.GetValue()
        params.projectname = self.m_text_ctrl_project_name.GetValue()
        params.artifactid = self.m_text_ctrl_artifact_id.GetValue()
        params.groupid = self.m_text_ctrl_group_id.GetValue()
        rbm_index = self.m_radio_box_mode.GetSelection()
        # 实例化核心修改类
        if rbm_index == 0:
            ry = ruoyi.RuoYi(params, configdict, templatedict, self.alter_callback)
        elif rbm_index == 1:
            ry = ruoyivue.RuoYiVue(params, configdict, templatedict, self.alter_callback)
        elif rbm_index == 2:
            ry = ruoyifast.RuoYiFast(params, configdict, templatedict, self.alter_callback)
        elif rbm_index == 3:
            ry = ruoyicloud.RuoYiCloud(params, configdict, templatedict, self.alter_callback)
        try:
            # 开始修改
            ry.start()

        except Exception as error:
            self.show_operate_log('-------------------\n\r')
            self.show_operate_log('修改发生异常：\n{}'.format(error))
            self.show_operate_log('\r----------------------')
            logger.error('修改发生异常：{}', error)
        finally:
            # 切换当前工作目录
            os.chdir(globals()[constant.APP_WORK_DIRECTORY])
            logger.info('修改完成，输出目录：{}', target_dir)
            globals()['output_directory'] = target_dir
            self.m_btn_open_output_directory.Enable()
            #启用按钮
            self.m_btn_start.Enable()
            self.m_btn_clear.Enable()
            self.show_operate_log('输出目录：' + target_dir)
            self.show_operate_log('任务结束!')

    # 实现开始执行按钮的事件
    def OnClickEventStart(self, event):
        selectpath = self.m_filePicker.GetPath()
        if len(selectpath) == 0:
            self.show_message('请选择文件')
            return
        if selectpath.endswith('.zip') is False:
            self.show_message('请选择标准的.zip文件')
            return
        if os.path.exists(selectpath) is False:
            self.show_message('请选择有效的.zip文件')
            return
        message = self.check_input()
        if len(message) != 0:
            self.show_message(message)
            return
        dlg = wx.MessageDialog(None, '确认开始执行吗？', '操作提醒', wx.YES_NO)
        if dlg.ShowModal() == wx.ID_YES:
            dlg.Destroy()
            t = threading.Thread(target=self.start_task, args=(selectpath, ))
            t.start()

    # 实现退出菜单事件
    def OnMenuClickEventExit(self, event):
        dlg = wx.MessageDialog(None, '确认退出程序吗？', '退出提醒', wx.YES_NO)
        if dlg.ShowModal() == wx.ID_YES:
            self.Destroy()
        dlg.Destroy()

    def OnMenuClickEventConfig(self, event):
        dlg = ui.config.config.Config(self)
        dlg.ShowModal()
        dlg.Destroy()

    def OnMenuClickEventTemplateConfig(self, event):
        dlg = ui.config.templateConfig.TemplateConfig(self)
        dlg.ShowModal()
        dlg.Destroy()

    # 实现清空按钮的事件
    def OnClickEventClear(self, event):
        self.m_filePicker.SetPath('')
        self.m_text_ctrl_project_dir_name.SetValue('')
        self.m_text_ctrl_project_name.SetValue('')
        self.m_text_ctrl_package_name.SetValue('')
        self.m_text_ctrl_artifact_id.SetValue('')
        self.m_text_ctrl_group_id.SetValue('')
        self.m_text_ctrl_site_name.SetValue('')
        self.m_text_log.SetValue('')
        self.m_btn_open_output_directory.Disable()
        self.m_radio_box_mode.SetSelection(0)

    # 实现打开输出目录按钮的事件
    def OnClickEventOpenOutputDirectory(self, event):
        directory = globals()['output_directory']
        try:
            os.startfile(directory)
        except:
            subprocess.Popen(['open', directory])

    # 实现打赏作者事件
    def OnMenuClickEventReward(self, event):
        dlg = ui.reward.Reward(self)
        dlg.ShowModal()
        dlg.Destroy()

    # 实现druid秘钥生成事件
    def OnMenuClickEventDruidEncrypt(self, event):
        dlg = ui.druidencrypt.DruidEncrypt(self)
        dlg.ShowModal()
        dlg.Destroy()

    # 实现批量删除文件事件
    def OnMenuClickEventDeleteFile(self, event):
        dlg = ui.filedel.FileDel(self)
        dlg.ShowModal()
        dlg.Destroy()

    # 实现关于事件
    def OnAbout(self, event):
        dlg = ui.about.About(self)
        dlg.ShowModal()
        dlg.Destroy()

    # 实现检测更新事件
    def OnUpgrade(self, event):
        upgradespider.check(True)

    # 实现使用指南事件
    def OnManual(self, event):
        dlg = ui.manual.Manual(self)
        dlg.ShowModal()
        dlg.Destroy()
